﻿// Decompiled with JetBrains decompiler
// Type: MCM.Implementation.BaseJsonSettingsFormat
// Assembly: MCMv5, Version=5.10.2.0, Culture=neutral, PublicKeyToken=null
// MVID: 7AB326B9-B2B4-41C2-9177-68E944071101
// Assembly location: D:\steam\steamapps\workshop\content\261550\2859238197\bin\Win64_Shipping_Client\MCMv5.dll

using BUTR.DependencyInjection;
using BUTR.DependencyInjection.Logger;
using MCM.Abstractions;
using MCM.Abstractions.Base;
using MCM.Abstractions.GameFeatures;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;

#nullable enable
namespace MCM.Implementation
{
  public abstract class BaseJsonSettingsFormat : ISettingsFormat
  {
    private readonly object _lock = new object();
    protected readonly Dictionary<string, object?> _existingObjects = new Dictionary<string, object>();
    protected readonly IBUTRLogger Logger;

    protected virtual JsonSerializerSettings JsonSerializerSettings { get; }

    protected BaseJsonSettingsFormat(IBUTRLogger logger)
    {
      this.Logger = logger;
      JsonSerializerSettings serializerSettings = new JsonSerializerSettings();
      serializerSettings.Formatting = Formatting.Indented;
      serializerSettings.Converters.Add((JsonConverter) new BaseSettingsJsonConverter(logger, new Action<string, object>(this.AddSerializationProperty), new Action(this.ClearSerializationProperties)));
      serializerSettings.Converters.Add((JsonConverter) new DropdownJsonConverter(logger, new Func<string, object>(this.GetSerializationProperty)));
      this.JsonSerializerSettings = serializerSettings;
    }

    public virtual IEnumerable<string> FormatTypes { get; } = (IEnumerable<string>) new string[1]
    {
      "json"
    };

    public string SaveJson(BaseSettings settings)
    {
      return JsonConvert.SerializeObject((object) settings, this.JsonSerializerSettings);
    }

    public BaseSettings LoadFromJson(BaseSettings settings, string content)
    {
      this.TryLoadFromJson(ref settings, content);
      return settings;
    }

    protected bool TryLoadFromJson(ref BaseSettings settings, string content)
    {
      lock (this._lock)
      {
        try
        {
          JObject jObject;
          if (!BaseJsonSettingsFormat.TryParse(content, out jObject))
            return false;
          using (JsonReader reader = jObject.CreateReader())
          {
            JsonSerializer serializer = JsonSerializer.CreateDefault(this.JsonSerializerSettings);
            Type type = settings.GetType();
            BaseSettingsJsonConverter settingsJsonConverter = this.JsonSerializerSettings.Converters.OfType<BaseSettingsJsonConverter>().FirstOrDefault<BaseSettingsJsonConverter>();
            if (settingsJsonConverter != null && settingsJsonConverter.CanConvert(type))
              settingsJsonConverter.ReadJson(reader, type, (object) settings, serializer);
          }
        }
        catch (JsonSerializationException ex)
        {
          return false;
        }
      }
      return true;
    }

    public virtual bool Save(BaseSettings settings, GameDirectory directory, string filename)
    {
      IFileSystemProvider service = GenericServiceProvider.GetService<IFileSystemProvider>();
      if (service == null)
        return false;
      GameFile file = service.GetOrCreateFile(directory, filename + ".json");
      if (file == null)
        return false;
      string s = this.SaveJson(settings);
      try
      {
        return service.WriteData(file, Encoding.UTF8.GetBytes(s));
      }
      catch (Exception ex)
      {
        return false;
      }
    }

    public virtual BaseSettings Load(
      BaseSettings settings,
      GameDirectory directory,
      string filename)
    {
      IFileSystemProvider service = GenericServiceProvider.GetService<IFileSystemProvider>();
      if (service == null)
        return settings;
      GameFile file = service.GetFile(directory, filename + ".json");
      if (file == null)
        return settings;
      byte[] bytes = service.ReadData(file);
      if (bytes == null)
      {
        this.Save(settings, directory, filename);
        return settings;
      }
      try
      {
        if (!this.TryLoadFromJson(ref settings, Encoding.UTF8.GetString(bytes)))
          this.Save(settings, directory, filename);
      }
      catch (Exception ex)
      {
      }
      return settings;
    }

    protected object? GetSerializationProperty(string path)
    {
      lock (this._lock)
      {
        object obj;
        return this._existingObjects.TryGetValue(path, out obj) ? obj : (object) null;
      }
    }

    protected void AddSerializationProperty(string path, object? value)
    {
      this._existingObjects.Add(path, value);
    }

    protected void ClearSerializationProperties() => this._existingObjects.Clear();

    private static bool TryParse(string content, [NotNullWhen(true)] out JObject? jObject)
    {
      try
      {
        jObject = JObject.Parse(content);
        return true;
      }
      catch (JsonReaderException ex)
      {
        jObject = (JObject) null;
        return false;
      }
    }
  }
}
